package com.database.objects;

import java.util.*;

import com.google.common.collect.Lists;

public enum Type {

	COMMIT(true, "COMMIT", "COMMITS"), FILE(true, "FILE", "FILES"), FILE_OO(false, "JAVA FILE", "JAVA FILES"), FILE_NO_OO(false, "NO JAVA FILE", "NO JAVA FILES"), CLASS(true, "CLASS", "CLASSES"), METHOD(true, "METHOD", "METHODS"), LINE(true, "LINE",
			"LINES"), LINE_OO(false, "SLOC IN JAVA FILE", "SLOCS"), TASK(false, "TASK", "TASKS"), ENHANCEMENT(false, "ENHANCEMENT", "ENHANCEMENTS"), DEFECT(false, "DEFECT", "DEFECTS"), UNKNOWN(false, "UNKNOWN", "UNKNOWN");

	private static Map<Type, List<String>> similarMap = new HashMap<Type, List<String>>();

	static {
		List<String> similarDefect = Lists.newArrayList("BUG", "BUGS", "PATCHES");
		List<String> similarEnhancement = Lists.newArrayList("FEATUREREQUESTS");
		List<String> similarTask = Lists.newArrayList("SUPPORTREQUESTS");

		similarMap.put(DEFECT, similarDefect);
		similarMap.put(ENHANCEMENT, similarEnhancement);
		similarMap.put(TASK, similarTask);
	}

	private boolean selectable;

	private String name;

	private String text;

	private Type(boolean selectable, String name, String text) {
		this.selectable = selectable;
		this.name = name;
		this.text = text;
	}

	public static Type createType(String value) {
		value = processValue(value);
		try {
			return valueOf(value);
		} catch (Exception e) {
			Type similarValue = obtainSimilarValue(value);
			if (similarValue.isUnknown()) {
				e.printStackTrace();
			}
			return similarValue;
		}
	}

	public static String processValue(String value) {
		return value.trim().replace(" ", "").toUpperCase();
	}

	private static Type obtainSimilarValue(String value) {
		for (Type key : similarMap.keySet()) {
			for (String similar : similarMap.get(key)) {
				if (value.equals(similar)) {
					return key;
				}
			}
		}
		return UNKNOWN;
	}

	public boolean isSelectable() {
		return selectable;
	}

	public String getName() {
		return name;
	}

	public String getText() {
		return text;
	}

	public boolean isCommit() {
		return equals(COMMIT);
	}

	public boolean isFile() {
		return equals(FILE);
	}

	public boolean isFileOO() {
		return equals(FILE_OO);
	}

	public boolean isFileNoOO() {
		return equals(FILE_NO_OO);
	}

	public boolean isClass() {
		return equals(CLASS);
	}

	public boolean isMethod() {
		return equals(METHOD);
	}

	public boolean isLine() {
		return equals(LINE);
	}

	public boolean isLineOO() {
		return equals(LINE_OO);
	}

	public boolean isTask() {
		return equals(TASK);
	}

	public boolean isEnhancement() {
		return equals(ENHANCEMENT);
	}

	public boolean isDefect() {
		return equals(DEFECT);
	}

	public boolean isUnknown() {
		return equals(UNKNOWN);
	}

	public boolean impliesFile() {
		return isFile() || impliesClass();
	}

	public boolean impliesClass() {
		return isClass() || impliesMethod();
	}

	public boolean impliesMethod() {
		return isMethod() || impliesLine();
	}

	public boolean impliesLine() {
		return isLine();
	}

	public static List<Type> selectableValues() {
		List<Type> selectableValues = new ArrayList<Type>();
		for (Type value : values()) {
			if (value.isSelectable()) {
				selectableValues.add(value);
			}
		}
		return selectableValues;
	}

	public static Type valueOfText(String text) {
		for (Type type : values()) {
			if (type.getText().equals(text)) {
				return type;
			}
		}
		return null;
	}

}